#include "cppTutorTCPSocketServer.h"

// log framework
#include "cppTutorLog.h"
CcppTutorLog Log;

// gtlog framework
#include "Log.h"
extern class CLog g_tLog;
 
using namespace std;

// CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer () : iSin_size (0), iSockfd (0), iClientfd (0), iRet (-1), iServerPort (0), iLogin (1), m_nReturnStatus (1), iOpenfd (0), iWriteNum (0)
// {
	// Log << "ENTER : CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer ()" << endl;
    
	// pLogin 	= "user";
	// pPasswd = "1234";
	
	// cLogin  = "login  :";
	// cPasswd = "passwd :";
	
    // Log << "EXIT  : CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer ()" << endl;
// }

CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer (string strPort = "999") : iSin_size (0), iSockfd (0), iClientfd (0), iRet (-1), iServerPort (0), iLogin (1), m_nReturnStatus (1), iOpenfd (0), iWriteNum (0), m_strPort (strPort)
{
	Log << "ENTER : CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer ()" << endl;
    
	pLogin 	= "user";
	pPasswd = "1234";
	
	cLogin  = "login  :";
	cPasswd = "passwd :";
	
    Log << "EXIT  : CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer ()" << endl;
}

CcppTutorTCPSocketServer :: ~CcppTutorTCPSocketServer ()
{
	Log << "ENTER : CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer ()" << endl;
	Log << "EXIT  : CcppTutorTCPSocketServer :: CcppTutorTCPSocketServer ()" << endl;
}

int CcppTutorTCPSocketServer :: ServerMain( )
{
	Log << "ENTER : CcppTutorTCPSocketServer :: ServerMain ()" << endl;
    string strLogName = "TCPServer";
    Log << "Port = " << m_strPort  << endl;
    Log << "Log  = " << strLogName << endl;
	iServerPort = atoi ( m_strPort.c_str() );
	snprintf ( pLogName , sizeof ( pLogName ) , "%s" , strLogName.c_str() );

//	while ( iSockfd == -1 ) {
	iSockfd = socket ( AF_INET , SOCK_STREAM , 0 );
	if ( iSockfd == -1 ) 
	{
		Log << "SM : Socket Found error !\n";
		exit ( 1 );
	}	
	Log << "SM : Socket Found Success !\n";
//	}

	server_addr.sin_family = AF_INET;
	//server_addr.sin_port = htons ( SERVER_PORT );
	server_addr.sin_port = htons ( iServerPort );
	server_addr.sin_addr.s_addr = htonl ( INADDR_ANY );	
	bzero ( & ( server_addr.sin_zero ) , 8 );

	if ( bind ( iSockfd , ( struct sockaddr * )&server_addr , sizeof ( struct sockaddr ) ) == -1 )
	{
		Log << "SM : Bind Error !\n";
		exit ( 1 );
	}
	Log << "SM : Bind Success !\n";

	if ( listen ( iSockfd , BACKLOG ) == -1 ) 
	{
		Log << "SM : Listen Error !\n";
		exit ( 1 );
	}
	Log << "SM : Listen Success !\n";
	Log << "SM : Listen Port : " << iServerPort << endl;

	while ( 1 ) 
	{
		iSin_size = sizeof ( struct sockaddr_in );
		if ( ( iClientfd = accept ( iSockfd , ( struct sockaddr * )&client_addr , (socklen_t*)&iSin_size ) ) == -1 ) 
		{
			Log << "SM : Accept Error !\n";
		}
		else 
		{
			Log  << "SM : Accept Success !\n";
			cout << "Receive a Connection From : " << inet_ntoa( client_addr.sin_addr ) << endl;

			iLogin = 1;
			while ( iLogin == 1 ) 
			{
				iRet = -1;
				while ( iRet == -1 ) 
				{
					iRet = send ( iClientfd , cLogin , strlen( cLogin ) , 0 );
					if ( iRet == -1 )
					{
						Log << "SM : Send Error !\n";
					}
				}
				iRet = -1;
		
				while ( iRet == -1 || iRet == 0 ) 
				{
					memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );
					iRet = recv ( iClientfd , sReceiveBuff , RECEIVE_BUFF_SIZE , 0 ); 
					if ( iRet == -1 )
					{
						Log << "SM : Receive Error !\n";
					}
				}
				strcpy ( sLogin , sReceiveBuff ) ;
				iRet = -1;

				while ( iRet == -1 ) 
				{
					iRet = send ( iClientfd , cPasswd , strlen( cPasswd ) , 0 );
					if ( iRet == -1 ) {
						Log << "SM : Send Error !\n";
					}
				}
				iRet = -1;

				while ( iRet == -1 || iRet == 0 ) 
				{
					memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );
					iRet = recv ( iClientfd , sReceiveBuff , RECEIVE_BUFF_SIZE , 0 ); 
					if ( iRet == -1 ) 
					{
						Log << "SM : Receive Error !\n";
					}
				}
				strcpy ( sPasswd , sReceiveBuff ) ;
				//memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );

				if ( ( strcmp ( sLogin , pLogin ) == 0 ) && (strcmp ( sPasswd , pPasswd ) == 0 ) ) 
				{
					iRet = send ( iClientfd , "Login Success !" , 16 , 0 );
					if ( iRet == -1 ) 
					{
						Log << "SM : Send Error !\n";
					}
					iLogin = 0;
				} 
				else 
				{
					iRet = send ( iClientfd , "Login Failure !" , 16 , 0 );
					iLogin = 1;
					iRet = -1;
				}
			}
			while ( 1 )
			{
				memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );
				iRet = recv ( iClientfd , sReceiveBuff , RECEIVE_BUFF_SIZE , 0 );	
				if ( iRet == -1 ) 
				{
					Log << "SM : Receive Error !\n";
				}
				else if ( iRet == 0 ) 
				{
					cout << "Client Closed !\n";
					close ( iClientfd );
					break;
				}
				else 
				{
					cout << "Client Message : " << sReceiveBuff << endl;
					memset ( sPrintLogBuff , 0 , sizeof ( sPrintLogBuff ) );
					snprintf ( sPrintLogBuff , sizeof ( sKeyBoardInput ) , "Client Message : %s\n" , sReceiveBuff );
					iWriteLogServer ( pLogName , sPrintLogBuff );
				}

				cout << "Server Message : " << endl;
				//scanf ( "%s" , &sKeyBoardInput ); 
				cin >> sKeyBoardInput; 
				//printf ( "KEY = %s\n" , sKeyBoardInput );
				memset ( sPrintLogBuff , 0 , sizeof ( sPrintLogBuff ) );
				snprintf ( sPrintLogBuff , sizeof ( sReceiveBuff ) , "Server Message : %s\n" , sKeyBoardInput );
				iWriteLogServer ( pLogName , sKeyBoardInput );

				iRet = send ( iClientfd , sKeyBoardInput , strlen( sKeyBoardInput ) , 0 );
				if ( iRet == -1 )
				{
					Log << "SM : Send Error !\n";
				}
			}
		}
	}
	Log << "EXIT  : CcppTutorTCPSocketServer :: ClientMain () [" << m_nReturnStatus << " : " << __LINE__ << "]"<< endl;
	return m_nReturnStatus;
}

int CcppTutorTCPSocketServer :: iWriteLogServer (char * pFileName, char * pLogBuff)
{
	Log << "ENTER : CcppTutorTCPSocketServer :: iWriteLogServer ()" << endl;

	iOpenfd = open ( pFileName , O_APPEND|O_RDWR|O_CREAT , S_IRWXU );
	iWriteNum = write (iOpenfd , pLogBuff , strlen ( pLogBuff ) );

	Log << "EXIT  : CcppTutorTCPSocketClient :: ClientMain () [" << iWriteNum << " : " << __LINE__ << "]"<< endl;
	return iWriteNum;
}

int main (int argc, char **argv)
{
    CcppTutorTCPSocketServer tcpserver;
	// if ( argc < 2 )
	// {
    //      printf ( "Usage : %s parameter\n" , argv[0] );
	// }
    tcpserver.ServerMain ();
    return 0;
}